home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / diropus4.12b_gpl / dopus_disk / install.c < prev    next >
C/C++ Source or Header  |  2000-01-27  |  12KB  |  461 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "diskop.h"
  32.  
  33. enum {
  34.     INSTALL_FFS,
  35.     INSTALL_INSTALL,
  36.     INSTALL_NOBOOT,
  37.     INSTALL_CANCEL};
  38.  
  39. struct TagItem
  40.     install_device_list[]={
  41.         {RO_Type,OBJECT_LISTVIEW},
  42.         {RO_ListViewID,0},
  43.         {RO_LeftFine,2},
  44.         {RO_Width,10},
  45.         {RO_Height,6},
  46.         {RO_HeightFine,30},
  47.         {RO_HighRecess,TRUE},
  48.         {TAG_END,0}},
  49.  
  50.     install_ffs_gadget[]={
  51.         {RO_Type,OBJECT_GADGET},
  52.         {RO_GadgetType,GADGET_CHECK},
  53.         {RO_GadgetID,INSTALL_FFS},
  54.         {RO_Left,14},
  55.         {RO_TextNum,STR_FORMAT_FFS},
  56.         {RO_TextPos,TEXTPOS_RIGHT},
  57.         {RO_ChkCenter,TRUE},
  58.         {TAG_END,0}},
  59.  
  60.     install_install_gadget[]={
  61.         {RO_Type,OBJECT_GADGET},
  62.         {RO_GadgetType,GADGET_BOOLEAN},
  63.         {RO_GadgetID,INSTALL_INSTALL},
  64.         {RO_Top,8},
  65.         {RO_TopFine,37},
  66.         {RO_Width,13},
  67.         {RO_Height,1},
  68.         {RO_HeightFine,4},
  69.         {RO_TextNum,STR_INSTALL_INSTALL},
  70.         {RO_TextPos,TEXTPOS_CENTER},
  71.         {RO_HighRecess,TRUE},
  72.         {TAG_END,0}},
  73.     install_noboot_gadget[]={
  74.         {RO_Type,OBJECT_GADGET},
  75.         {RO_GadgetType,GADGET_BOOLEAN},
  76.         {RO_GadgetID,INSTALL_NOBOOT},
  77.         {RO_Left,14},
  78.         {RO_Top,8},
  79.         {RO_TopFine,37},
  80.         {RO_Width,13},
  81.         {RO_Height,1},
  82.         {RO_HeightFine,4},
  83.         {RO_TextNum,STR_INSTALL_NOBOOT},
  84.         {RO_TextPos,TEXTPOS_CENTER},
  85.         {RO_HighRecess,TRUE},
  86.         {TAG_END,0}},
  87.     install_cancel_gadget[]={
  88.         {RO_Type,OBJECT_GADGET},
  89.         {RO_GadgetType,GADGET_BOOLEAN},
  90.         {RO_GadgetID,INSTALL_CANCEL},
  91.         {RO_Left,28},
  92.         {RO_Top,8},
  93.         {RO_TopFine,37},
  94.         {RO_Width,13},
  95.         {RO_Height,1},
  96.         {RO_HeightFine,4},
  97.         {RO_TextNum,STR_FORMAT_EXIT},
  98.         {RO_TextPos,TEXTPOS_CENTER},
  99.         {RO_HighRecess,TRUE},
  100.         {TAG_END,0}},
  101.  
  102.     install_info_box[]={
  103.         {RO_Type,OBJECT_BORDER},
  104.         {RO_BorderType,BORDER_RECESSED},
  105.         {RO_LeftFine,2},
  106.         {RO_Top,7},
  107.         {RO_TopFine,28},
  108.         {RO_Width,41},
  109.         {RO_WidthFine,-4},
  110.         {RO_Height,1},
  111.         {RO_HeightFine,4},
  112.         {TAG_END,0}},
  113.  
  114.     *install_gadgets[]={
  115.         install_ffs_gadget,
  116.         install_install_gadget,
  117.         install_noboot_gadget,
  118.         install_cancel_gadget,
  119.         NULL};
  120.  
  121. void diskop_install(vis,argc,argv)
  122. struct VisInfo *vis;
  123. int argc;
  124. char *argv[];
  125. {
  126.     struct RequesterBase installreq;
  127.     struct Window *window;
  128.     struct IntuiMessage *msg;
  129.     Object_Border *infobox;
  130.     struct DOpusListView *devicelist,*view;
  131.     struct Gadget *gadlist;
  132.     ULONG class,mask;
  133.     USHORT code,gadgetid;
  134.     APTR iaddress;
  135.     int gadcount=0,ignorechange=0,a,b;
  136.     int start=-1,startffs=0,startnoboot=0;
  137.  
  138.     installreq.rb_width=41;
  139.     installreq.rb_height=9;
  140.     installreq.rb_widthfine=16;
  141.     installreq.rb_heightfine=54;
  142.     installreq.rb_leftoffset=8;
  143.     installreq.rb_topoffset=8;
  144.     installreq.rb_flags=0;
  145.  
  146.     fill_out_req(&installreq,vis);
  147.  
  148.     installreq.rb_privateflags=0;
  149.     installreq.rb_screenname=NULL;
  150.  
  151.     if (installreq.rb_screen && !(vis->vi_flags&VISF_BORDERS)) {
  152.         installreq.rb_flags|=RBF_STRINGS;
  153.         installreq.rb_title=NULL;
  154.     }
  155.     else {
  156.         installreq.rb_flags|=RBF_BORDERS|RBF_CLOSEGAD|RBF_STRINGS;
  157.         installreq.rb_title=string_table[STR_INSTALL_INSTALL];
  158.     }
  159.  
  160.     installreq.rb_extend=NULL;
  161.     installreq.rb_idcmpflags=0;
  162.     installreq.rb_string_table=string_table;
  163.  
  164.     if (SysBase->LibNode.lib_Version<36) mask=1;
  165.     else mask=0;
  166.  
  167.     if (!(window=OpenRequester(&installreq)) ||
  168.         !(gadlist=addreqgadgets(&installreq,install_gadgets,mask,&gadcount)) ||
  169.         !(infobox=(Object_Border *)
  170.             AddRequesterObject(&installreq,install_info_box)) ||
  171.         !(devicelist=(struct DOpusListView *)
  172.             AddRequesterObject(&installreq,install_device_list)) ||
  173.         !(devicelist->items=get_device_list(&installreq.rb_memory,"DF0:"))) {
  174.         CloseRequester(&installreq);
  175.         return;
  176.     }
  177.  
  178.     fix_listview(&installreq,devicelist);
  179.     get_env("install",gadlist,gadcount,devicelist);
  180.  
  181.     for (a=0;a<argc;a++) {
  182.         if (LStrCmpI(argv[a],"ffs")==0 && !mask) startffs=1;
  183.         else if (LStrCmpI(argv[a],"noboot")==0) startnoboot=1;
  184.         else {
  185.             if (start==-1) {
  186.                 for (b=0;devicelist->items[b];b++) {
  187.                     if (LStrCmpI(argv[a],devicelist->items[b])==0) {
  188.                         start=b;
  189.                         devicelist->itemselected=b;
  190.                         break;
  191.                     }
  192.                 }
  193.             }
  194.         }
  195.     }
  196.  
  197.     if (!(AddListView(devicelist,1))) {
  198.         CloseRequester(&installreq);
  199.         return;
  200.     }
  201.     show_sel_item(devicelist);
  202.  
  203.     if (start>-1) {
  204.         if (startffs) gadlist->Flags|=GFLG_SELECTED;
  205.         else gadlist->Flags&=~GFLG_SELECTED;
  206.     }
  207.  
  208.     RefreshRequesterObject(&installreq,NULL);
  209.     RefreshGList(gadlist,window,NULL,gadcount);
  210.     show_install_info(&installreq,infobox,devicelist->items[devicelist->itemselected]);
  211.  
  212.     if (start>-1) {
  213.         do_install(&installreq,infobox,
  214.             devicelist->items[devicelist->itemselected],
  215.             startnoboot,startffs);
  216.         RemoveListView(devicelist,1);
  217.         CloseRequester(&installreq);
  218.         return;
  219.     }
  220.  
  221.     FOREVER {
  222.         while (msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
  223.             if ((view=(struct DOpusListView *)ListViewIDCMP(devicelist,msg))==
  224.                 (struct DOpusListView *)-1) {
  225.                 class=msg->Class; code=msg->Code;
  226.                 iaddress=msg->IAddress;
  227.                 ReplyMsg((struct Message *)msg);
  228.  
  229.                 switch (class) {
  230.                     case IDCMP_DISKINSERTED:
  231.                     case IDCMP_DISKREMOVED:
  232.                         if (ignorechange) ignorechange=0;
  233.                         else {
  234.                             show_install_info(&installreq,
  235.                                 infobox,
  236.                                 devicelist->items[devicelist->itemselected]);
  237.                         }
  238.                         break;
  239.  
  240.                     case IDCMP_VANILLAKEY:    
  241.                         code=toupper(code);
  242.                         switch (code) {
  243.                             case 'F':
  244.                                 if (!mask) {
  245.                                     gadlist->Flags^=GFLG_SELECTED;
  246.                                     RefreshGList(gadlist,window,NULL,1);
  247.                                 }
  248.                                 break;
  249.                             case 0x1b:
  250.                                 set_env("install",gadlist,gadcount,devicelist);
  251.                                 RemoveListView(devicelist,1);
  252.                                 CloseRequester(&installreq);
  253.                                 return;
  254.                         }
  255.                         break;
  256.  
  257.                     case IDCMP_GADGETDOWN:
  258.                     case IDCMP_GADGETUP:
  259.                         gadgetid=((struct Gadget *)iaddress)->GadgetID;
  260.                     case IDCMP_CLOSEWINDOW:
  261.                         if (class==IDCMP_CLOSEWINDOW) gadgetid=INSTALL_CANCEL;
  262.  
  263.                         switch (gadgetid) {
  264.                             case INSTALL_CANCEL:
  265.                                 set_env("install",gadlist,gadcount,devicelist);
  266.                                 RemoveListView(devicelist,1);
  267.                                 CloseRequester(&installreq);
  268.                                 return;
  269.                             case INSTALL_INSTALL:
  270.                             case INSTALL_NOBOOT:
  271.                                 if (do_install(&installreq,infobox,
  272.                                     devicelist->items[devicelist->itemselected],
  273.                                     (gadgetid==INSTALL_NOBOOT),(!mask && gadlist->Flags&GFLG_SELECTED)))
  274.                                     ignorechange=1;
  275.                                 break;
  276.                         }
  277.                         break;
  278.                 }
  279.             }
  280.             else if (view) {
  281.                 show_install_info(&installreq,
  282.                     infobox,view->items[view->itemselected]);
  283.             }
  284.         }
  285.         Wait(1<<window->UserPort->mp_SigBit);
  286.     }
  287. }
  288.  
  289. void show_install_info(reqbase,border,name)
  290. struct RequesterBase *reqbase;
  291. Object_Border *border;
  292. char *name;
  293. {
  294.     struct DeviceHandle handle;
  295.     ULONG *buffer,tracksize,dostype;
  296.     char infobuf[80];
  297.     int a,sum,lastsum,ffs;
  298.  
  299.     border_text(reqbase,border,NULL);
  300.     strcpy(infobuf,string_table[STR_INSTALL_NOINFO]);
  301.  
  302.     if (open_device(name,&handle)) {
  303.         handle.device_req->iotd_Req.io_Command=TD_CHANGESTATE;
  304.         DoIO((struct IORequest *)handle.device_req);
  305.         if (handle.device_req->iotd_Req.io_Actual)
  306.             lsprintf(infobuf,string_table[STR_NODISKPRESENT],name);
  307.         else {
  308.             tracksize=(handle.dosenvec->de_SizeBlock<<2)*
  309.                 handle.dosenvec->de_Surfaces*handle.dosenvec->de_BlocksPerTrack,
  310.             drive_motor(handle.device_req,1);
  311.             if (buffer=(ULONG *)AllocMem(TD_SECTOR*2,handle.dosenvec->de_BufMemType)) {
  312.                 handle.device_req->iotd_Req.io_Command=CMD_READ;
  313.                 handle.device_req->iotd_Req.io_Data=(APTR)buffer;
  314.                 handle.device_req->iotd_Req.io_Offset=handle.dosenvec->de_LowCyl*tracksize;
  315.                 handle.device_req->iotd_Req.io_Length=TD_SECTOR*2;
  316.                 if (!(DoIO((struct IORequest *)handle.device_req))) {
  317.                     dostype=buffer[0];
  318.                     for (a=0,sum=0;a<TD_SECTOR>>1;a++) {
  319.                         lastsum=sum;
  320.                         sum+=buffer[a];
  321.                         if (lastsum>sum) ++sum;
  322.                     }
  323.                     if (sum!=0) strcpy(infobuf,string_table[STR_INSTALL_NOTBOOTABLE]);
  324.                     else {
  325.                         if (dostype&1) ffs=1;
  326.                         else ffs=0;
  327.  
  328.                         if (install_compare_block(buffer,bootblock_13,13)) {
  329.                             lsprintf(infobuf,string_table[STR_INSTALL_NORMAL],
  330.                                 "1.3",(ffs)?"FFS":"OFS");
  331.                         }
  332.                         else if (install_compare_block(buffer,bootblock_20,24)) {
  333.                             lsprintf(infobuf,string_table[STR_INSTALL_NORMAL],
  334.                                 "2.0+",(ffs)?"FFS":"OFS");
  335.                             if ((dostype&0xfffffffe)==ID_INTER_DOS_DISK)
  336.                                 strcat(infobuf," (Inter)");
  337.                             else if ((dostype&0xfffffffe)==ID_FASTDIR_DOS_DISK)
  338.                                 strcat(infobuf," (Cache)");
  339.                         }
  340.                         else strcpy(infobuf,string_table[STR_INSTALL_NONSTANDARD]);
  341.                     }
  342.                 }
  343.                 FreeMem(buffer,TD_SECTOR*2);
  344.             }
  345.         }
  346.         drive_motor(handle.device_req,0);
  347.     }
  348.     close_device(&handle);
  349.     border_text(reqbase,border,infobuf);
  350. }
  351.  
  352. install_compare_block(block,testblock,size)
  353. ULONG *block,*testblock,size;
  354. {
  355.     int a;
  356.  
  357.     for (a=3;a<size;a++)
  358.         if (block[a]!=testblock[a])
  359.             return(0);
  360.     return(1);
  361. }
  362.  
  363. do_install(reqbase,border,device,noboot,forceffs)
  364. struct RequesterBase *reqbase;
  365. Object_Border *border;
  366. char *device;
  367. int noboot,forceffs;
  368. {
  369.     struct DeviceHandle handle;
  370.     ULONG dostype;
  371.     ULONG *buffer,tracksize;
  372.     BPTR lock;
  373.     struct InfoData __aligned data;
  374.     int a,err=STR_SUCCESS,sum,lastsum;
  375.     struct Requester busyreq;
  376.  
  377.     InitRequester(&busyreq);
  378.     busyreq.Flags=NOISYREQ;
  379.     Request(&busyreq,reqbase->rb_window);
  380.     SetBusyPointer(reqbase->rb_window);
  381.  
  382.     if (open_device(device,&handle)) {
  383.         border_text(reqbase,border,string_table[STR_CHECKING_DESTINATION]);
  384.         drive_motor(handle.device_req,1);
  385.         tracksize=(handle.dosenvec->de_SizeBlock<<2)*
  386.             handle.dosenvec->de_Surfaces*handle.dosenvec->de_BlocksPerTrack;
  387.  
  388.         if (check_disk(reqbase,handle.device_req,device,1)) {
  389.             if (lock=Lock(device,ACCESS_READ)) {
  390.                 Info(lock,&data);
  391.                 UnLock(lock);
  392.  
  393.                 dostype=data.id_DiskType;
  394.  
  395.                 border_text(reqbase,border,string_table[STR_INSTALL_INSTALLINGDISK]);
  396.  
  397.                 if ((dostype&~(0xff))==0x444f5300) {
  398.                     if (forceffs) dostype|=1;
  399.                     if (buffer=(ULONG *)AllocMem(TD_SECTOR*2,handle.dosenvec->de_BufMemType|MEMF_CLEAR)) {
  400.  
  401.                         if (noboot) buffer[0]=dostype;
  402.                         else {
  403.                             if (SysBase->LibNode.lib_Version<36)
  404.                                 CopyMem((char *)bootblock_13,(char *)buffer,sizeof(bootblock_13));
  405.                             else CopyMem((char *)bootblock_20,(char *)buffer,sizeof(bootblock_20));
  406.  
  407.                             buffer[0]=dostype;
  408.  
  409.                             for (a=0,sum=0;a<TD_SECTOR>>1;a++) {
  410.                                 lastsum=sum;
  411.                                 sum+=buffer[a];
  412.                                 if (lastsum>sum) ++sum;
  413.                             }
  414.  
  415.                             buffer[1]=~sum;
  416.                         }
  417.  
  418.                         inhibit_drive(device,DOSTRUE);
  419.  
  420.                         FOREVER {
  421.                             handle.device_req->iotd_Req.io_Command=CMD_WRITE;
  422.                             handle.device_req->iotd_Req.io_Data=(APTR)buffer;
  423.                             handle.device_req->iotd_Req.io_Offset=handle.dosenvec->de_LowCyl*tracksize;
  424.                             handle.device_req->iotd_Req.io_Length=TD_SECTOR*2;
  425.  
  426.                             if (!(DoIO((struct IORequest *)handle.device_req))) {
  427.                                 handle.device_req->iotd_Req.io_Command=CMD_UPDATE;
  428.                                 if (!(DoIO((struct IORequest *)handle.device_req))) break;
  429.                             }
  430.  
  431.                             border_text(reqbase,border,string_table[STR_INSTALL_ERRORWRITING]);
  432.                             if (!(check_error(reqbase,string_table[STR_INSTALL_ERRORWRITING],STR_RETRY))) {
  433.                                 err=-1;
  434.                                 break;
  435.                             }
  436.                         }
  437.  
  438.                         inhibit_drive(device,FALSE);
  439.                         FreeMem(buffer,TD_SECTOR*2);
  440.                     }
  441.                     else err=STR_MEMORY_ERROR;
  442.                 }
  443.                 else err=STR_INVALID_DISK;
  444.             }
  445.             else err=STR_INVALID_DISK;
  446.         }
  447.         else err=STR_ABORTED;
  448.  
  449.         drive_motor(handle.device_req,0);
  450.     }
  451.     else err=STR_NODEVICE_ERROR;
  452.  
  453.     if (err>-1) border_text(reqbase,border,string_table[err]);
  454.  
  455.     close_device(&handle);
  456.  
  457.     EndRequest(&busyreq,reqbase->rb_window);
  458.     ClearPointer(reqbase->rb_window);
  459.     return((err==STR_SUCCESS));
  460. }
  461.